﻿

namespace Test
 module StateMachine = 

    open System
    open System.Windows
    open System.Windows.Media
    open System.Windows.Shapes
    open System.Windows.Controls
    open FsSignals.Signal
      
    module Safe = 
        type Safe = 
            {
                buttonA : Button
                buttonB : Button
                buttonC : Button
                button1 : Button
                button2 : Button
                button3 : Button

                enableLetterButton : bool -> unit
                enableNumButton : bool -> unit

                resetButton : Button

                text : TextBox
            }
        
        let initSafe () = 
            let safe =
              {
                buttonA = new Button()
                buttonB = new Button()
                buttonC = new Button()
                button1 = new Button()
                button2 = new Button()
                button3 = new Button()

                resetButton = new Button()

                text = new  TextBox()

                enableLetterButton = fun _ -> ()
                enableNumButton = fun _ -> ()
             }
            
            safe.buttonA.Content <- "A"
            safe.buttonB.Content <- "B"
            safe.buttonC.Content <- "C"
            safe.button1.Content <- "1"
            safe.button2.Content <- "2"
            safe.button3.Content <- "3"
            safe.resetButton.Content <- "Start Again"
            safe.text.Text <- "Safe is Closed"

            let sp1 = new StackPanel()
            sp1.Margin <- new Thickness(10.0)
            let lbsp = new StackPanel()
            lbsp.Orientation <- Orientation.Horizontal 
            lbsp.HorizontalAlignment <- HorizontalAlignment.Left
            lbsp.Children.Add(safe.buttonA)
            lbsp.Children.Add(safe.buttonB)
            lbsp.Children.Add(safe.buttonC)
            
            let nbsp = new StackPanel()
            nbsp.Orientation <- Orientation.Horizontal 
            nbsp.HorizontalAlignment <- HorizontalAlignment.Left
            nbsp.Children.Add(safe.button1)
            nbsp.Children.Add(safe.button2)
            nbsp.Children.Add(safe.button3)

            sp1.Children.Add(lbsp)
            sp1.Children.Add(nbsp)
            sp1.Children.Add(safe.resetButton)
            sp1.Children.Add(safe.text)

            let elb b = lbsp.IsEnabled <- b
            let enb b = nbsp.IsEnabled <- b
            (sp1, {safe with enableLetterButton = elb ; enableNumButton = enb})


        let makeScanPanel () =
            let (panel, safe) = initSafe ()
            let letterButtons = [safe.buttonA; safe.buttonB; safe.buttonC]
            let numButtons = [safe.button1; safe.button2; safe.button3]
            
            let enableButton bs state = List.iter (fun (b:Button) -> b.IsEnabled <- state) bs

            let rec engine() =
                safe.text.Text <- "Safe is Closed"
                safe.enableLetterButton true
                safe.enableNumButton false

                let resetSig = sourceEvent  safe.resetButton.Click =>> (fun v -> ()) =>> engine 
                let state3() = 
                    safe.enableNumButton false
                    safe.text.Text <- "Safe is Open"
                    wait resetSig

                let state2() = 
                    safe.enableLetterButton false
                    safe.enableNumButton true

                    let numSig = sourceEvent safe.button1.Click --> ()
                    switch (onceThen numSig state3) resetSig
                    //onceThen numSig state3
                        
                let letterSig = sourceEvent safe.buttonA.Click --> ()
                switch (onceThen letterSig state2) resetSig
                //onceThen letterSig state2

            engine();
            panel